home *** CD-ROM | disk | FTP | other *** search
- /* xform.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Id: xform.c,v 1.22 1995/10/31 19:40:35 brianp Exp $
-
- $Log: xform.c,v $
- * Revision 1.22 1995/10/31 19:40:35 brianp
- * removed INLINE macro, more trouble than it was worth
- *
- * Revision 1.21 1995/10/16 15:26:56 brianp
- * replaced dd_buffer_info with DD.buffer_size call
- *
- * Revision 1.20 1995/09/30 15:35:13 brianp
- * added test for identity texture matrix in gl_mult_matrix
- *
- * Revision 1.19 1995/09/27 18:31:40 brianp
- * added gl_transform_normals
- *
- * Revision 1.18 1995/09/26 16:05:26 brianp
- * removed gl_transform_point, gl_transform_normal
- * added gl_transform_points
- *
- * Revision 1.17 1995/09/13 14:42:23 brianp
- * added logic to test for identity texture matrix
- *
- * Revision 1.16 1995/07/24 20:35:20 brianp
- * replaced memset() with MEMSET() and memcpy() with MEMCPY()
- *
- * Revision 1.15 1995/07/24 18:58:28 brianp
- * correct gl_viewport() semantics, introduced CC.ClipSpans flag
- *
- * Revision 1.14 1995/06/21 15:11:08 brianp
- * better allocation policy for depth, stencil buffer in gl_viewport
- *
- * Revision 1.13 1995/06/20 16:26:32 brianp
- * removed fudge value from viewport transformation scale and translation
- *
- * Revision 1.12 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.11 1995/05/12 16:57:22 brianp
- * replaced CC.Mode!=0 with INSIDE_BEGIN_END
- *
- * Revision 1.10 1995/04/19 13:48:18 brianp
- * renamed occurances of near and far for SCO x86 Unix
- *
- * Revision 1.9 1995/04/01 16:17:47 brianp
- * fixed mult_matrix bug in glTranslatef and glScalef
- *
- * Revision 1.8 1995/03/28 16:10:33 brianp
- * removed singular matrix error message
- *
- * Revision 1.7 1995/03/22 21:37:47 brianp
- * removed mode from dd_buffer_info()
- *
- * Revision 1.6 1995/03/10 17:13:20 brianp
- * new matmul and invert_matrix functions from Thomas Malik
- *
- * Revision 1.5 1995/03/10 15:19:43 brianp
- * added divide by zero check to gl_transform_normal
- *
- * Revision 1.4 1995/03/09 21:42:30 brianp
- * new ModelViewInv matrix logic
- *
- * Revision 1.3 1995/03/09 20:08:48 brianp
- * changed order of arguments to gl_transform_ functions to be more logical
- *
- * Revision 1.2 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.1 1995/02/24 14:28:31 brianp
- * Initial revision
- *
- */
-
-
- /*
- * Geometry Transformation.
- *
- *
- * NOTES:
- * 1. 4x4 transformation matrices are stored in memory in column major order.
- * 2. Points/vertices are to be thought of as column vectors.
- * 3. Transformation of a point p by a matrix M is: p' = M * p
- *
- */
-
-
-
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "context.h"
- #include "depth.h"
- #include "dd.h"
- #include "list.h"
- #include "macros.h"
- #include "stencil.h"
-
-
-
- #ifndef M_PI
- # define M_PI (3.1415926)
- #endif
-
-
-
- static GLfloat Identity[16] = {
- 1.0, 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0
- };
-
-
-
-
- #ifdef DEBUG
- static void print_matrix( const GLfloat m[16] )
- {
- int i;
-
- for (i=0;i<4;i++) {
- printf("%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
- }
- }
- #endif
-
-
-
- /*
- * Perform a 4x4 matrix multiplication (product = a x b).
- * Input: a, b - matrices to multiply
- * Output: product - product of a and b
- */
- static void
- matmul( GLfloat *product, const GLfloat *a, const GLfloat *b )
- {
- /* This matmul was contributed by Thomas Malik */
- GLfloat temp[16];
- GLint i;
-
- #define A(row,col) a[(col<<2)+row]
- #define B(row,col) b[(col<<2)+row]
- #define T(row,col) temp[(col<<2)+row]
-
- /* i-te Zeile */
- for (i = 0; i < 4; i++)
- {
- T(i, 0) = A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i, 3) * B(3, 0);
- T(i, 1) = A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i, 3) * B(3, 1);
- T(i, 2) = A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i, 3) * B(3, 2);
- T(i, 3) = A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i, 3) * B(3, 3);
- }
-
- #undef A
- #undef B
- #undef T
- MEMCPY( product, temp, 16*sizeof(GLfloat) );
- }
-
-
-
- /*
- * Find the inverse of the 4 by 4 matrix b using gausian elimination
- * and return it in a.
- *
- * This function was contributed by Thomas Malik (malik@rhrk.uni-kl.de).
- * Thanks Thomas!
- */
- static void invert_matrix(const GLfloat *b,GLfloat * a)
- {
- #define MAT(m,r,c) ((m)[(c)*4+(r)])
-
- GLfloat val, val2;
- GLint i, j, k, ind;
- GLfloat tmp[16];
-
- MEMCPY(a,Identity,sizeof(float)*16);
- MEMCPY(tmp, b,sizeof(float)*16);
-
- for (i = 0; i != 4; i++) {
-
- val = MAT(tmp,i,i); /* find pivot */
- ind = i;
- for (j = i + 1; j != 4; j++) {
- if (fabs(MAT(tmp,j,i)) > fabs(val)) {
- ind = j;
- val = MAT(tmp,j,i);
- }
- }
-
- if (ind != i) { /* swap columns */
- for (j = 0; j != 4; j++) {
- val2 = MAT(a,i,j);
- MAT(a,i,j) = MAT(a,ind,j);
- MAT(a,ind,j) = val2;
- val2 = MAT(tmp,i,j);
- MAT(tmp,i,j) = MAT(tmp,ind,j);
- MAT(tmp,ind,j) = val2;
- }
- }
-
- if (val == 0.0F) {
- /* The matrix is singular (has no inverse). This isn't really
- * an error since singular matrices can be used for projecting
- * shadows, etc. We let the inverse be the identity matrix.
- */
- /*fprintf(stderr,"Singular matrix, no inverse!\n");*/
- MEMCPY( a, Identity, 16*sizeof(GLfloat) );
- return;
- }
-
- for (j = 0; j != 4; j++) {
- MAT(tmp,i,j) /= val;
- MAT(a,i,j) /= val;
- }
-
- for (j = 0; j != 4; j++) { /* eliminate column */
- if (j == i)
- continue;
- val = MAT(tmp,j,i);
- for (k = 0; k != 4; k++) {
- MAT(tmp,j,k) -= MAT(tmp,i,k) * val;
- MAT(a,j,k) -= MAT(a,i,k) * val;
- }
- }
- }
- #undef MAT
- }
-
-
-
-
- /*
- * Compute the inverse of the current ModelViewMatrix.
- */
- void gl_compute_modelview_inverse( void )
- {
- invert_matrix( CC.ModelViewMatrix, CC.ModelViewInv );
- CC.ModelViewInvValid = GL_TRUE;
- }
-
-
-
- /*
- * Apply a transformation matrix to an array of coordinates:
- * for i in 0 to n-1 do q[i] = m * p[i]
- * where p[i] and q[i] are 4-element column vectors and m is a 16-element
- * transformation matrix.
- */
- void gl_transform_points( GLuint n, GLfloat q[][4], const GLfloat m[16],
- GLfloat p[][4] )
- {
- /* This function has been carefully crafted to maximize register usage
- * and use loop unrolling with IRIX 5.3's cc. Hopefully other compilers
- * will like this code too.
- */
- {
- GLuint i;
- GLfloat m0 = m[0];
- GLfloat m4 = m[4];
- GLfloat m8 = m[8];
- GLfloat m12 = m[12];
- GLfloat m1 = m[1];
- GLfloat m5 = m[5];
- GLfloat m9 = m[9];
- GLfloat m13 = m[13];
- for (i=0;i<n;i++) {
- GLfloat p0 = p[i][0], p1 = p[i][1], p2 = p[i][2], p3 = p[i][3];
- q[i][0] = m0 * p0 + m4 * p1 + m8 * p2 + m12 * p3;
- q[i][1] = m1 * p0 + m5 * p1 + m9 * p2 + m13 * p3;
- }
- }
- {
- GLuint i;
- GLfloat m2 = m[2];
- GLfloat m6 = m[6];
- GLfloat m10 = m[10];
- GLfloat m14 = m[14];
- GLfloat m3 = m[3];
- GLfloat m7 = m[7];
- GLfloat m11 = m[11];
- GLfloat m15 = m[15];
- for (i=0;i<n;i++) {
- GLfloat p0 = p[i][0], p1 = p[i][1], p2 = p[i][2], p3 = p[i][3];
- q[i][2] = m2 * p0 + m6 * p1 + m10 * p2 + m14 * p3;
- q[i][3] = m3 * p0 + m7 * p1 + m11 * p2 + m15 * p3;
- }
- }
- }
-
-
-
- /*
- * Apply a transformation matrix to an array of normal vectors:
- * for i in 0 to n-1 do v[i] = u[i] * m
- * where u[i] and v[i] are 3-element row vectors and m is a 16-element
- * transformation matrix.
- * If the normalize flag is true the normals will be scaled to length 1.
- */
- void gl_transform_normals( GLuint n, GLfloat v[][3], const GLfloat m[16],
- GLfloat u[][3], GLboolean normalize )
- {
- if (normalize) {
- /* Transform normals and scale to unit length */
- GLuint i;
- GLfloat m0 = m[0], m4 = m[4], m8 = m[8];
- GLfloat m1 = m[1], m5 = m[5], m9 = m[9];
- GLfloat m2 = m[2], m6 = m[6], m10 = m[10];
- for (i=0;i<n;i++) {
- GLdouble tx, ty, tz;
- {
- GLfloat ux = u[i][0], uy = u[i][1], uz = u[i][2];
- tx = ux * m0 + uy * m1 + uz * m2;
- ty = ux * m4 + uy * m5 + uz * m6;
- tz = ux * m8 + uy * m9 + uz * m10;
- }
- {
- GLdouble len, scale;
- len = sqrt( tx*tx + ty*ty + tz*tz );
- scale = (len>0.00001) ? (1.0 / len) : 1.0;
- v[i][0] = tx * scale;
- v[i][1] = ty * scale;
- v[i][2] = tz * scale;
- }
- }
- }
- else {
- /* Just transform normals, don't scale */
- GLuint i;
- GLfloat m0 = m[0], m4 = m[4], m8 = m[8];
- GLfloat m1 = m[1], m5 = m[5], m9 = m[9];
- GLfloat m2 = m[2], m6 = m[6], m10 = m[10];
- for (i=0;i<n;i++) {
- GLfloat ux = u[i][0], uy = u[i][1], uz = u[i][2];
- v[i][0] = ux * m0 + uy * m1 + uz * m2;
- v[i][1] = ux * m4 + uy * m5 + uz * m6;
- v[i][2] = ux * m8 + uy * m9 + uz * m10;
- }
- }
- }
-
-
-
- /*
- * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This
- * function is used for transforming clipping plane equations and spotlight
- * directions.
- * Mathematically, u = v * m.
- * Input: v - input vector
- * m - transformation matrix
- * Output: u - transformed vector
- */
- void gl_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] )
- {
- #define M(row,col) m[col*4+row]
- u[0] = v[0] * M(0,0) + v[1] * M(1,0) + v[2] * M(2,0) + v[3] * M(3,0);
- u[1] = v[0] * M(0,1) + v[1] * M(1,1) + v[2] * M(2,1) + v[3] * M(3,1);
- u[2] = v[0] * M(0,2) + v[1] * M(1,2) + v[2] * M(2,2) + v[3] * M(3,2);
- u[3] = v[0] * M(0,3) + v[1] * M(1,3) + v[2] * M(2,3) + v[3] * M(3,3);
- #undef M
- }
-
-
-
- void glMatrixMode( GLenum mode )
- {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glMatrixMode" );
- return;
- }
-
- switch (mode) {
- case GL_MODELVIEW:
- case GL_PROJECTION:
- case GL_TEXTURE:
- if (CC.CompileFlag) {
- gl_save_set_enum( &CC.Transform.MatrixMode, mode );
- }
- if (CC.ExecuteFlag) {
- CC.Transform.MatrixMode = mode;
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glMatrixMode" );
- }
- }
-
-
-
- void glOrtho( GLdouble left, GLdouble right,
- GLdouble bottom, GLdouble top,
- GLdouble nearval, GLdouble farval )
- {
- GLfloat x, y, z;
- GLfloat tx, ty, tz;
- GLfloat m[16];
-
- x = 2.0 / (right-left);
- y = 2.0 / (top-bottom);
- z = -2.0 / (farval-nearval);
- tx = -(right+left) / (right-left);
- ty = -(top+bottom) / (top-bottom);
- tz = -(farval+nearval) / (farval-nearval);
-
- #define M(row,col) m[col*4+row]
- M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx;
- M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty;
- M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz;
- M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F;
- #undef M
-
- glMultMatrixf( m );
- }
-
-
-
- void glFrustum( GLdouble left, GLdouble right,
- GLdouble bottom, GLdouble top,
- GLdouble nearval, GLdouble farval )
- {
- GLfloat x, y, a, b, c, d;
- GLfloat m[16];
-
- if (nearval<=0.0 || farval<=0.0) {
- gl_error( GL_INVALID_VALUE, "glFrustum(near or far)" );
- }
-
- x = (2.0*nearval) / (right-left);
- y = (2.0*nearval) / (top-bottom);
- a = (right+left) / (right-left);
- b = (top+bottom) / (top-bottom);
- c = -(farval+nearval) / ( farval-nearval);
- d = -(2.0*farval*nearval) / (farval-nearval); /* error? */
-
- #define M(row,col) m[col*4+row]
- M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
- M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
- M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
- M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
- #undef M
-
- glMultMatrixf( m );
- }
-
-
-
- /*
- * Define a new viewport and reallocate auxillary buffers if the size of
- * the window (color buffer) has changed.
- */
- void gl_viewport( GLint x, GLint y, GLsizei width, GLsizei height )
- {
- GLint newsize;
- GLuint buf_width, buf_height, buf_depth;
-
- if (width<0 || height<0) {
- gl_error( GL_INVALID_VALUE, "glViewport" );
- return;
- }
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glViewport" );
- return;
- }
-
- #ifdef LEAVEOUT
- /* clamp x, y, width, and height to implementation dependent range */
- x = CLAMP( x, 0, MAX_WIDTH-1 );
- y = CLAMP( y, 0, MAX_HEIGHT-1 );
- if (width<1) {
- width = 1;
- }
- if (height<1) {
- height = 1;
- }
- if (x+width>MAX_WIDTH) {
- width = MAX_WIDTH - x;
- }
- if (y+height>MAX_HEIGHT) {
- height = MAX_HEIGHT - y;
- }
- #endif
-
- /* ask device driver for size of output buffer */
- (*DD.buffer_size)( &buf_width, &buf_height, &buf_depth );
-
- /* see if size of device driver buffer has changed */
- newsize = CC.BufferWidth!=buf_width || CC.BufferHeight!=buf_height;
-
- /* save buffer size */
- CC.BufferWidth = buf_width;
- CC.BufferHeight = buf_height;
-
- /* Save viewport */
- CC.Viewport.X = x;
- CC.Viewport.Width = width;
- CC.Viewport.Y = y;
- CC.Viewport.Height = height;
-
- /* compute scale and bias values */
- CC.Viewport.Sx = (GLfloat) width / 2.0F;
- CC.Viewport.Tx = CC.Viewport.Sx + x;
- CC.Viewport.Sy = (GLfloat) height / 2.0F;
- CC.Viewport.Ty = CC.Viewport.Sy + y;
-
- /* Reallocate other buffers if needed. */
- if (newsize && CC.DepthBuffer) {
- /* reallocate depth buffer, if there is one */
- gl_alloc_depth_buffer();
- }
- if (newsize && CC.StencilBuffer) {
- /* reallocate stencil buffer, if there is one */
- gl_alloc_stencil_buffer();
- }
- if (newsize && CC.AccumBuffer) {
- /* Deallocate the accumulation buffer. A new one will be allocated */
- /* if/when glAccum() is called again. */
- free( CC.AccumBuffer );
- CC.AccumBuffer = NULL;
- }
-
- /* If viewport extends beyond window bounds we have to clip pixel spans */
- if (x<0 || y<0 || x+width>CC.BufferWidth || y+height>CC.BufferHeight) {
- CC.ClipSpans = GL_TRUE;
- }
- else {
- CC.ClipSpans = GL_FALSE;
- }
- }
-
-
-
- void glViewport( GLint x, GLint y, GLsizei width, GLsizei height )
- {
- if (CC.ExecuteFlag) {
- gl_viewport( x, y, width, height );
- }
- if (CC.CompileFlag) {
- gl_save_viewport( x, y, width, height );
- }
- }
-
-
-
-
- /*
- * Determine if the given matrix is the identity matrix.
- */
- static GLboolean is_identity( const GLfloat m[16] )
- {
- if ( m[0]==1.0F && m[4]==0.0F && m[ 8]==0.0F && m[12]==0.0F
- && m[1]==0.0F && m[5]==1.0F && m[ 9]==0.0F && m[13]==0.0F
- && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F
- && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
- }
-
-
-
-
- void glPushMatrix( void )
- {
- if (CC.CompileFlag) {
- gl_save_pushmatrix();
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glPopMatrix" );
- return;
- }
- switch (CC.Transform.MatrixMode) {
- case GL_MODELVIEW:
- if (CC.ModelViewStackDepth>=MAX_MODELVIEW_STACK_DEPTH-1) {
- gl_error( GL_STACK_OVERFLOW, "glPushMatrix");
- return;
- }
- MEMCPY( CC.ModelViewStack[CC.ModelViewStackDepth],
- CC.ModelViewMatrix,
- 16*sizeof(GLfloat) );
- CC.ModelViewStackDepth++;
- break;
- case GL_PROJECTION:
- if (CC.ProjectionStackDepth>=MAX_PROJECTION_STACK_DEPTH) {
- gl_error( GL_STACK_OVERFLOW, "glPushMatrix");
- return;
- }
- MEMCPY( CC.ProjectionStack[CC.ProjectionStackDepth],
- CC.ProjectionMatrix,
- 16*sizeof(GLfloat) );
- CC.ProjectionStackDepth++;
- break;
- case GL_TEXTURE:
- if (CC.TextureStackDepth>=MAX_TEXTURE_STACK_DEPTH) {
- gl_error( GL_STACK_OVERFLOW, "glPushMatrix");
- return;
- }
- MEMCPY( CC.TextureStack[CC.TextureStackDepth],
- CC.TextureMatrix,
- 16*sizeof(GLfloat) );
- CC.TextureStackDepth++;
- break;
- }
- }
- }
-
-
-
- void glPopMatrix( void )
- {
- if (CC.CompileFlag) {
- gl_save_popmatrix();
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glPopMatrix" );
- return;
- }
- switch (CC.Transform.MatrixMode) {
- case GL_MODELVIEW:
- if (CC.ModelViewStackDepth==0) {
- gl_error( GL_STACK_UNDERFLOW, "glPop");
- return;
- }
- CC.ModelViewStackDepth--;
- MEMCPY( CC.ModelViewMatrix,
- CC.ModelViewStack[CC.ModelViewStackDepth],
- 16*sizeof(GLfloat) );
- CC.ModelViewInvValid = GL_FALSE;
- break;
- case GL_PROJECTION:
- if (CC.ProjectionStackDepth==0) {
- gl_error( GL_STACK_UNDERFLOW, "glPop");
- return;
- }
- CC.ProjectionStackDepth--;
- MEMCPY( CC.ProjectionMatrix,
- CC.ProjectionStack[CC.ProjectionStackDepth],
- 16*sizeof(GLfloat) );
- break;
- case GL_TEXTURE:
- if (CC.TextureStackDepth==0) {
- gl_error( GL_STACK_UNDERFLOW, "glPop");
- return;
- }
- CC.TextureStackDepth--;
- MEMCPY( CC.TextureMatrix,
- CC.TextureStack[CC.TextureStackDepth],
- 16*sizeof(GLfloat) );
- CC.IdentityTexMat = is_identity( CC.TextureMatrix );
- break;
- }
- }
- }
-
-
-
- void gl_load_matrix( const GLfloat *m )
- {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glLoadMatrix" );
- return;
- }
- switch (CC.Transform.MatrixMode) {
- case GL_MODELVIEW:
- MEMCPY( CC.ModelViewMatrix, m, 16*sizeof(GLfloat) );
- CC.ModelViewInvValid = GL_FALSE;
- break;
- case GL_PROJECTION:
- MEMCPY( CC.ProjectionMatrix, m, 16*sizeof(GLfloat) );
- break;
- case GL_TEXTURE:
- MEMCPY( CC.TextureMatrix, m, 16*sizeof(GLfloat) );
- CC.IdentityTexMat = is_identity( CC.TextureMatrix );
- break;
- }
- }
-
-
-
- void glLoadMatrixd( const GLdouble *m )
- {
- GLfloat fm[16];
- GLuint i;
-
- for (i=0;i<16;i++) {
- fm[i] = (GLfloat) m[i];
- }
-
- glLoadMatrixf( fm );
- }
-
-
-
- void glLoadMatrixf( const GLfloat *m )
- {
- if (CC.CompileFlag) {
- gl_save_loadmatrix( m );
- }
- if (CC.ExecuteFlag) {
- gl_load_matrix( m );
- }
- }
-
-
-
- void glLoadIdentity( void )
- {
- if (CC.CompileFlag) {
- gl_save_loadmatrix( Identity );
- }
- if (CC.ExecuteFlag) {
- gl_load_matrix( Identity );
- }
- }
-
-
-
- void gl_mult_matrix( const GLfloat *m )
- {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glMultMatrix" );
- return;
- }
- switch (CC.Transform.MatrixMode) {
- case GL_MODELVIEW:
- matmul( CC.ModelViewMatrix, CC.ModelViewMatrix, m );
- CC.ModelViewInvValid = GL_FALSE;
- break;
- case GL_PROJECTION:
- matmul( CC.ProjectionMatrix, CC.ProjectionMatrix, m );
- break;
- case GL_TEXTURE:
- matmul( CC.TextureMatrix, CC.TextureMatrix, m );
- CC.IdentityTexMat = is_identity( CC.TextureMatrix );
- break;
- }
- }
-
-
-
- void glMultMatrixd( const GLdouble *m )
- {
- GLfloat fm[16];
- GLuint i;
-
- for (i=0;i<16;i++) {
- fm[i] = (GLfloat) m[i];
- }
-
- glMultMatrixf( fm );
- }
-
-
-
- void glMultMatrixf( const GLfloat *m )
- {
- if (CC.CompileFlag) {
- gl_save_multmatrix( m );
- }
- if (CC.ExecuteFlag) {
- gl_mult_matrix( m );
- }
- }
-
-
-
- void glRotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z )
- {
- glRotatef( (GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z );
- }
-
-
-
- void glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
- {
- /* This function contributed by Erich Boleyn (erich@uruk.org) */
-
- GLfloat m[16];
- GLfloat mag, s, c;
- GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
-
- s = sin( angle * (M_PI / 180.0) );
- c = cos( angle * (M_PI / 180.0) );
-
- mag = sqrt( x*x + y*y + z*z );
-
- if (mag == 0.0)
- return;
-
- x /= mag;
- y /= mag;
- z /= mag;
-
- #define M(row,col) m[col*4+row]
-
- /*
- * Arbitrary axis rotation matrix.
- *
- * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
- * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation
- * (which is about the X-axis), and the two composite transforms
- * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
- * from the arbitrary axis to the X-axis then back. They are
- * all elementary rotations.
- *
- * Rz' is a rotation about the Z-axis, to bring the axis vector
- * into the x-z plane. Then Ry' is applied, rotating about the
- * Y-axis to bring the axis vector parallel with the X-axis. The
- * rotation about the X-axis is then performed. Ry and Rz are
- * simply the respective inverse transforms to bring the arbitrary
- * axis back to it's original orientation. The first transforms
- * Rz' and Ry' are considered inverses, since the data from the
- * arbitrary axis gives you info on how to get to it, not how
- * to get away from it, and an inverse must be applied.
- *
- * The basic calculation used is to recognize that the arbitrary
- * axis vector (x, y, z), since it is of unit length, actually
- * represents the sines and cosines of the angles to rotate the
- * X-axis to the same orientation, with theta being the angle about
- * Z and phi the angle about Y (in the order described above)
- * as follows:
- *
- * cos ( theta ) = x / sqrt ( 1 - z^2 )
- * sin ( theta ) = y / sqrt ( 1 - z^2 )
- *
- * cos ( phi ) = sqrt ( 1 - z^2 )
- * sin ( phi ) = z
- *
- * Note that cos ( phi ) can further be inserted to the above
- * formulas:
- *
- * cos ( theta ) = x / cos ( phi )
- * sin ( theta ) = y / sin ( phi )
- *
- * ...etc. Because of those relations and the standard trigonometric
- * relations, it is pssible to reduce the transforms down to what
- * is used below. It may be that any primary axis chosen will give the
- * same results (modulo a sign convention) using thie method.
- *
- * Particularly nice is to notice that all divisions that might
- * have caused trouble when parallel to certain planes or
- * axis go away with care paid to reducing the expressions.
- * After checking, it does perform correctly under all cases, since
- * in all the cases of division where the denominator would have
- * been zero, the numerator would have been zero as well, giving
- * the expected result.
- */
-
- xx = x * x;
- yy = y * y;
- zz = z * z;
- xy = x * y;
- yz = y * z;
- zx = z * x;
- xs = x * s;
- ys = y * s;
- zs = z * s;
- one_c = 1.0F - c;
-
- M(0,0) = (one_c * xx) + c;
- M(0,1) = (one_c * xy) - zs;
- M(0,2) = (one_c * zx) + ys;
- M(0,3) = 0.0F;
-
- M(1,0) = (one_c * xy) + zs;
- M(1,1) = (one_c * yy) + c;
- M(1,2) = (one_c * yz) - xs;
- M(1,3) = 0.0F;
-
- M(2,0) = (one_c * zx) - ys;
- M(2,1) = (one_c * yz) + xs;
- M(2,2) = (one_c * zz) + c;
- M(2,3) = 0.0F;
-
- M(3,0) = 0.0F;
- M(3,1) = 0.0F;
- M(3,2) = 0.0F;
- M(3,3) = 1.0F;
-
- #undef M
-
- if (CC.CompileFlag) {
- gl_save_multmatrix( m );
- }
- if (CC.ExecuteFlag) {
- gl_mult_matrix( m );
- }
- }
-
-
-
- void glScaled( GLdouble x, GLdouble y, GLdouble z )
- {
- glScalef( (GLfloat) x, (GLfloat) y, (GLfloat) z );
- }
-
-
-
- void glScalef( GLfloat x, GLfloat y, GLfloat z )
- {
- GLfloat m[16];
-
- #define M(row,col) m[col*4+row]
- M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = 0.0F;
- M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = 0.0F;
- M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = 0.0F;
- M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F;
- #undef M
-
- if (CC.CompileFlag) {
- gl_save_multmatrix( m );
- }
- if (CC.ExecuteFlag) {
- gl_mult_matrix( m );
- }
- }
-
-
-
-
- void glTranslated( GLdouble x, GLdouble y, GLdouble z )
- {
- glTranslatef( (GLfloat) x, (GLfloat) y, (GLfloat) z );
- }
-
-
-
- void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
- {
- GLfloat m[16];
-
- #define M(row,col) m[col*4+row]
- M(0,0) = 1.0F; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = x;
- M(1,0) = 0.0F; M(1,1) = 1.0F; M(1,2) = 0.0F; M(1,3) = y;
- M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = 1.0F; M(2,3) = z;
- M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F;
- #undef M
-
- if (CC.CompileFlag) {
- gl_save_multmatrix( m );
- }
- if (CC.ExecuteFlag) {
- gl_mult_matrix( m );
- }
- }
-